package myJs.cps

import com.softwaremill.quicklens._
import myJs.Implicits._
import myJs.myPkg.Select2Options
import myJs.myPkg.jquery.{$, JQuery}
import org.scalajs.dom.{Event, html}
import slinky.core.{Component, FunctionalComponent}
import slinky.core.annotations.react
import slinky.core.facade.Hooks.{useEffect, useState}
import slinky.core.facade.{React, ReactElement}
import slinky.web.html.{className, name, ref, select, style}

import scala.collection.immutable.SeqMap
import scala.scalajs.js
import scala.scalajs.js.JSConverters._

/**
 * Created by yz on 21/1/2022
 */
@react object PureSelect2Cp {

  case class Props(name: String = "", optionMap: SeqMap[String, String], hasBv: Boolean = false, formJq: JQuery = $("#form"),
                   value: js.UndefOr[String] = js.undefined, onChange: js.UndefOr[String => Unit] = js.undefined,
                   width: String = "150px", allowClear: Boolean = false, disabled: Boolean = false)

  val component = FunctionalComponent[Props] { props =>

    val (value, setValue) = useState(props.optionMap.keyList.headOption.getOrElse(""))

    val selectRef = React.createRef[html.Select]
    val placeholder = "click to choose"

    useEffect(() => {
      val y = selectRef.current
      val jq = $(y)
      val data = props.optionMap.map { case (id, text) =>
        js.Dictionary("id" -> id, "text" -> text)
      }.toJSArray
      val options = Select2Options(data = data, allowClear = props.allowClear, placeholder = placeholder,
        disabled = props.disabled)
      jq.mySelect2(options)
      jq.select2Val(getValue)
      jq.on("change", (e: Event) => {
        val v = $(y).select2ValSingle
        onChange(v)
      })
      if (props.hasBv) {
        val bv = props.formJq.bv
        val curJq = $(y)
        bv.addField(curJq)
      }
      () => {
        val y = selectRef.current
        if (props.hasBv) {
          val bv = props.formJq.bv
          val curJq = $(y)
          bv.updateStatus(curJq, "VALID").removeField(curJq)
        }
      }
    }, List()
    )

    useEffect(() => {
      val y = selectRef.current
      val jq = $(y)
      val data = props.optionMap.map { case (id, text) =>
        js.Dictionary("id" -> id, "text" -> text)
      }.toJSArray
      val options = Select2Options(data = data, allowClear = props.allowClear, placeholder = placeholder,
        disabled = props.disabled)
      jq.mySelect2(options)
    }, List(props.optionMap)
    )

    useEffect(() => {
      val y = selectRef.current
      val jq = $(y)
      jq.select2Val(getValue)
    }, List(props.value)
    )

    def getValue = {
      props.value.map(v => v).getOrElse(value)
    }

    def onChange(v: String) = {
      props.onChange.toOption match {
        case Some(f) => f(v)
        case None => setValue(v)
      }
    }

    select(className := "form-control", name := s"${props.name}",
      style := Style(
        width = s"${props.width}"
      ), ref := selectRef
    )

  }

}
